/*
 * @Description: 属性封装
 * @notes: 
 * @Author: 台火山
 * @Date: 2024-03-24 15:51:19
 * @LastEditors: 郭火山 280118497@qq.com
 * @LastEditTime: 2024-03-24 18:54:38
 */

(function () {
    // 定义一个表示人的类
    class Person {
        // TS 可以在属性前添加属性的修饰符
        /**
         *  public 修饰的属性可以在任意位置访问(修改)默认值
         *  private 私有属性，只能在类内部进行访问(修改)
         *      通过在类中添加方法使得私有属性可以被外部访问
         *  protected 受保护的属性，只能在当前类和当前类的子类中使用(修改)
        */
        private name: string;
        private age: number;

        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }

        /**
         *  getter 方法用来读取属性
         *  setter 方法用来设置属性
         *      被称为存取器
         */

        // 定义方法，用来获取 name 属性
        getName() {
            return this.name;
        }

        // 定义方法，用来设置 name 属性
        setName(value: string) {
            this.name = value
        }

        getAge() {
            return this.age;
        }
        setAge(value: number) {
            // 判断年龄是否合法
            if (value >= 0) {
                this.age = value;
            }
        }

        /**
         *  TS 中设置 getter 方法方式
         *  
        */
        get names() {
            console.log('get-names执行了');

            return this.name
        }

        set names(value: string) {
            this.name = value
        }

    }

    const per = new Person('孙悟空', 15);

    /**
     *  现在属性实在对象中设置的，属性可以任意的被修改
     *      属性可以任意被修改将会导致对象中的数据变得非常不安全
     * 
    */
    // per.name = '猪八戒';
    // per.age = -38;

    console.log('per==', per);

    // 设置方法，获取数据
    console.log('getName==', per.getName());
    // 修改数据
    per.setName('猪八戒')
    per.setAge(33)
    console.log('per==', per);


    // ES6 新特性 数据劫持
    // 先去找get names
    console.log(per.names);
    // 存
    per.names = '222'
    console.log(per);

    class A {
        /**
         *  public 子也能访问
         *  private 子不能访问
         *  protected 只能在当前类额子类
         * */
        protected num: number;
        constructor(num: number) {
            this.num = num;
        }
    }
    class B extends A {
        test() {
            console.log(this.num);
        }
    }
    const b = new B(123)
    console.log('b==', b);

    class C {
        // 可以将属性定义在构造函数中
        constructor(public name: string, public age: number) {
            this.name = name;
            this.age = age;
        }
    }

    // 等价 -- 语法糖
   /*  class C {
        name: string;
        age: number;
        // 可以将属性定义在构造函数中
        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }
    } */

    const c = new C("悟空", 123);
    console.log('c==', c);


})();